﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TLang.Parsers
{
    using Ast;

    public static class Extensions
    {
        /// <summary>
        /// 不包括toIndex
        /// </summary>
        /// <param name="list"></param>
        /// <param name="fromIndex"></param>
        /// <param name="toIndex"></param>
        /// <returns></returns>
        public static List<Node> SubList(this List<Node> list, int fromIndex, int toIndex)
        {
            List<Node> results = new List<Node>(toIndex - fromIndex);
            for (int i = fromIndex; i < toIndex; i++)
            {
                results.Add(list[i]);
            }

            return results;
        }

        public static bool IsDelimType(this Node c, String d)
        {
            return c is DelimeterNode && ((DelimeterNode)c).Shape.Equals(d);
        }

        public static bool StartsWith(this string ss, string s, int offset)
        {
            if (ss.Length <= offset
                || ss.Length < s.Length
                || (ss.Length - offset) < s.Length)
            {
                return false;
            }
            for (int i = offset; i < s.Length + offset; i++)
            {
                if (ss[i] != s[i - offset])
                {
                    return false;
                }
            }
            return true;
        }

        public static bool IsWhiteSpace(this char ch)
        {
            return (ch == ' ') ||
                   (ch == '\t') ||
                   (ch == '\n') ||
                   (ch == '\r') ||
                   (ch == 65279);
        }

        public static bool IsNumberChar(this char c)
        {
            return Char.IsLetter(c) || Char.IsDigit(c) || c == '.' || c == '+' || c == '-';
        }

        public static bool IsIdentifierChar(this char c)
        {
            return Char.IsLetter(c) || Char.IsDigit(c) || Constants.IdentChars.Contains(c);
        }

        public static bool IsDelimiter(this char c)
        {
            return DelimeterNode.IsDelimiter(c);
        }

        public static bool IsOpen(this Node c)
        {
            return DelimeterNode.IsOpen(c);
        }

        public static bool IsClose(this Node c)
        {
            return DelimeterNode.IsClose(c);
        }

        public static bool IsMatch(this Node open, Node close)
        {
            return DelimeterNode.IsMatch(open, close);
        }
    }
}
